﻿using System;
using System.Diagnostics;
using xml=System.Xml;

namespace Co9320.NamaAlert.Engine.DebugHelper
{
	internal enum LogMode : byte
	{
		Notify = 0x01,
		Advisory = 0x02,
		Warning = 0x03,
		Caution = 0x04,
		Error = 0x05,
	}

	[DebuggerStepThrough]
	internal static class LogOutputter
	{
		private static xml::XmlWriter wtr;

		private static readonly object SyncRoot_ = new object();

		static LogOutputter()
		{
			lock (SyncRoot_)
			{
				xml::XmlWriterSettings setting = new System.Xml.XmlWriterSettings();
				setting.Indent = true;

				wtr = xml::XmlWriter.Create("log.xml", setting);

				wtr.WriteStartElement("Logging");
				wtr.WriteAttributeString("LoggingStart", DateTime.Now.ToString());
			}
		}

		[Conditional("LOGGING")]
		public static void PushElement(LogMode mode)
		{
			lock (SyncRoot_)
			{
				wtr.WriteStartElement(mode.ToString());
				wtr.WriteAttributeString("Time", DateTime.Now.ToString());
				wtr.Flush();
			}
		}

		[Conditional("LOGGING")]
		public static void PopElement()
		{
			lock (SyncRoot_)
			{
				wtr.WriteEndElement();
				wtr.Flush();
			}
		}

		[Conditional("LOGGING")]
		public static void WriteChildElement(string name, string value)
		{
			lock (SyncRoot_)
			{
				wtr.WriteStartElement(name);
				wtr.WriteString(value == null ? "NULL" : value);
				wtr.WriteEndElement();
				wtr.Flush();
			}
		}

		[Conditional("LOGGING")]
		public static void WriteChildElement(string name, string format, params object[] args)
		{
			lock (SyncRoot_)
			{
				WriteChildElement(name, string.Format(format, args));
			}
		}


		[Conditional("LOGGING")]
		public static void WriteElement(LogMode mode, Exception exception)
		{
			lock (SyncRoot_)
			{
				PushElement(mode);
				WriteChildElement("ExceptionType", exception.GetType().ToString());
				WriteChildElement("Message", exception.Message);
				WriteChildElement("Source", exception.Source);
				WriteChildElement("StackTrace", exception.StackTrace);
				PopElement();
			}
		}

		[Conditional("LOGGING")]
		public static void WriteElement(LogMode mode, string Description)
		{
			lock (SyncRoot_)
			{
				PushElement(mode);
				WriteChildElement("Description", Description);
				PopElement();
			}
		}

		[Conditional("LOGGING")]
		public static void WriteElement(LogMode mode, string descriptionFormat, params object[] args)
		{
			lock (SyncRoot_)
			{
				WriteElement(mode, string.Format(descriptionFormat, args));
			}
		}




		[Conditional("LOGGING")]
		public static void Close()
		{
			lock (SyncRoot_)
			{
				wtr.WriteEndElement();
				wtr.Close();
			}
		}

		[Conditional("LOGGING")]
		public static void OutputConsole(string value)
		{
			lock (SyncRoot_)
			{
				ConsoleControl.WriteLine(value == null ? "NULL" : value);
				WriteElement(LogMode.Notify, value);
			}
		}

		[Conditional("LOGGING")]
		public static void OutputConsole()
		{
			lock (SyncRoot_)
			{
				ConsoleControl.WriteLine();
			}
		}

		[Conditional("LOGGING")]
		public static void OutputConsole(string format, params object[] args)
		{
			lock (SyncRoot_)
			{
				ConsoleControl.WriteLine(format, args);
				WriteElement(LogMode.Notify, format, args);
			}
		}




	}



}
